package se.webbzon.boltzmann.game.event;

import java.util.ArrayList;
import java.util.Collection;

import se.webbzon.oschi01.worldarea.WorldArea;

public abstract class AbstractGameEvent {
	
	// A collection of all the listeners to this game event
	private Collection<GameEventListener> listeners;
	
	// The arguments of this abstract game event
	private String[] arguments;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public AbstractGameEvent() {
		this(null);
	}
	
	public AbstractGameEvent(String[] arguments) {
		listeners = new ArrayList<GameEventListener>();
		this.arguments = arguments;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Adds a listener to this game event. **/
	public boolean addListener(GameEventListener listener) {
		return listeners.add(listener);
	}
	
	/** Removes a listener from this game event. **/
	public boolean removeListener(GameEventListener listener) {
		return listeners.remove(listener);
	}
	
	/** Clears all listeners in this game event. **/
	public boolean clearListener(GameEventListener listener) {
		return listeners.add(listener);
	}
	
	/** Returns the number of arguments **/
	public int arguments() {
		if (arguments == null)
			return 0;
		else
			return arguments.length;
	}
	
	/** Returns the (n+1):th argument of this game event. **/
	public String getArgument(int n) {
		return arguments[n];
	}
	
	/** Starts this game event in the given world. **/
	public final void begin(WorldArea world) {
		for (GameEventListener listener : listeners.toArray(new GameEventListener[0]))
			listener.onBegin(this);
		onBegin(world);
	}
	
	/** End this game event. **/
	public final void end() {
		onEnd();
		for (GameEventListener listener : listeners.toArray(new GameEventListener[0]))
			listener.onEnd(this);
	}
	
	/*============================================================
	Protected Methods
	============================================================*/
	
	/** This method is invoked when the game event begins. **/
	protected abstract void onBegin(WorldArea world);
	
	/** This method is invoked when the game event ends. **/
	protected abstract void onEnd();
	
	/** Throws a new game event exception with the given message. **/
	protected void exception(String msg) {
		throw new GameEventException(msg);
	}

}
